'use strict';
const path = require('path');
const fse = require('fs-extra');
const pkgDir = require('pkg-dir').sync;
const pathExists = require('path-exists').sync;
const npmInstall = require('npminstall');
const { isObject } = require('@yuyd-cli-dev/utils');

const formatPath = require('@yuyd-cli-dev/format-path');
const { getDefultRegistry, getNpmLatestVersion } = require('@yuyd-cli-dev/get-npm-info');

class Package {
  constructor(options) {
    if (!options) {
      throw new Error('Package类的options参数不能为空！');
    }
    if (!isObject(options)) {
      throw new Error('Package类的options参数必须为对象！');
    }

    // package的数据
    this.targetPath = options.targetPath;
    // 缓存package的路径
    this.storeDir = options.storeDir;
    // // package 的name
    this.packageName = options.packageName;
    // // package 的 version
    this.packageVersion = options.packageVersion;
    // package的缓存目录前缀
    this.cacheFilePathPrefix = this.packageName.replace('/', '_');
  }

  async prepare() {
    if (this.storeDir && !pathExists(this.storeDir)) {
      fse.mkdirpSync(this.storeDir);
    }

    if (this.packageVersion === 'latest') {
      this.packageVersion = await getNpmLatestVersion(this.packageName);
    }
  }

  get cacheFilePath() {
    // _@imooc-cli_init@1.1.2@@imooc-cli/
    // @imooc-cli/init 1.1.2
    // _@imooc-cli_init@1.1.2@@imooc-cli/
    return path.resolve(
      this.storeDir,
      `_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`
    );
  }
  getSpeficCacheFilePath(packageVersion) {
    return path.resolve(
      this.storeDir,
      `_${this.cacheFilePrePath}@${packageVersion}@${this.packageName}`
    );
  }

  // 判断档期Package时候存在
  async exists() {
    if (this.storeDir) {
      // 缓存模式
      await this.prepare();
      return pathExists(this.cacheFilePath);
    } else {
      return await pathExists(this.targetPath);
    }
  }
  // 安装Package
  async install() {
    await this.prepare();
    return npmInstall({
      root: this.targetPath,
      storeDir: this.storeDir,
      rejistry: getDefultRegistry(),
      pkgs: [
        {
          name: this.packageName,
          version: this.packageVersion
        }
      ]
    });
  }
  // 更新Package
  async update() {
    await this.prepare();
    // 1. 获取最新的npm模块版本号
    const latestPackageVersion = await getNpmLatestVersion(this.packageName);
    console.log('latestPackageVersion', latestPackageVersion);
    // 2. 查询最新版本号对象的路径是否存在
    const latestFilePath = this.getSpeficCacheFilePath(latestPackageVersion);
    // 3. 如果不存在，则直接安装最新版本
    if (!pathExists(latestFilePath)) {
      await npmInstall({
        root: this.targetPath,
        storeDir: this.storeDir,
        rejistry: getDefultRegistry(),
        pkgs: [
          {
            name: this.packageName,
            version: latestPackageVersion
          }
        ]
      });
      this.packageVersion = latestPackageVersion;
    } else {
      this.packageVersion = latestPackageVersion;
    }
  }

  // 获取入口文件路径
  getRootFilePath() {
    const targetPath = this.targetPath;
    function _getRootFile(filePath) {
      // 1. 获取package.json所在目录 - pkg-dir
      const dir = pkgDir(filePath);
      if (dir) {
        // 2. 读取package.json - require() js/json/node
        const pkgFile = require(path.resolve(dir, 'package.json'));
        // 3. main/lib - path
        if (pkgFile && pkgFile.main) {
          // 4. 路径的兼容（macOS/windows）
          return formatPath(path.resolve(dir, pkgFile.main));
        }
      }
      return null;
      // 4. 路径的兼容（macOS/windows）
    }
    if (this.storeDir) {
      // 使用缓存
      return _getRootFile(this.cacheFilePath);
    } else {
      return _getRootFile(this.targetPath);
    }
  }
}
module.exports = Package;
